#ifndef NEWSMANAGER_H
#define NEWSMANAGER_H

#include "Archivo.h"
#include "RegistroFijoNewsIndex.h"
#include "RegistroVariableNewsData.h"
#include "RegistroVariableNewsDataCategoria.h"
#include "Feed.h"
#include "News.h"
#include <list>
#include <set>

class NewsItemConsulta
{
        private:
                TCId feedId;
                string descripcion;
                string titulo;
                TCTimeStamp fecha;
                TCPosicionEnLista posicion;
                ListaCategorias listaPositivos;
                ListaCategorias listaNegativos;
        public:
                NewsItemConsulta();
                virtual ~NewsItemConsulta();

                TCId getFeedId();
                string getDescripcion();
                string getTitulo();
                TCTimeStamp getFecha();
                TCPosicionEnLista getPosicion();
                ListaCategorias* getListaPositivosReferencia();
                ListaCategorias* getListaNegativosReferencia();
                
                void setFeedId(TCId value);
                void setDescripcion(string value);
                void setTitulo(string value);
                void setFecha(TCTimeStamp value);
                void setPosicion(TCPosicionEnLista value);
};

typedef list<NewsItemConsulta> ListaConsultaNoticias;
typedef set<TCPosicionEnLista> ConjuntoPosiciones;
typedef set<TCId> ConjuntoFeeds;
typedef set<int> ConjuntoIdCategoria;

class NewsManager
{
        private:
                string directorioBase;

                //recibe punteros a los archivos que esta usando y una noticia y la agrega.
                //devuelve la posicion relativa donde la agrego (o -1 si es error)
                int AgregarNoticia(Archivo* pArchivoDatos, Archivo* pArchivoIndice,
                        Archivo* pArchivoDatosCategoria, News &nuevaNoticia);

                bool Internal_AddCategoriaNoticia(Archivo* pArchivoIndice,
                        Archivo* pArchivoDatosCategoria, TCId categoria,
                                TCPosicionEnLista posicionNoticia, bool Positiva);

                string IdToString(TCId id);
                
        public:
                NewsManager();
                virtual ~NewsManager();

                //Recibe un Feed que contiene una lista de noticias y las Agrega a los archivos.
                bool AgregarNews(TCId feedId, Feed &nuevoFeed);

                //Recibe un News que contiene una noticia y la Agrega al Feed Indicado.
                //Si hay error devuelve -1
                TCId AgregarNews(TCId feedId, News &nuevaNoticia);

                bool InicializarManager(string DirectorioInicial);

                //Recibe un Id de Feed y da de baja todas las noticias del feed.
                bool EliminarNews(TCId feedId);

                //Recibe las posiciones en el Indice, el ID de Feed y retorna una lista
                //de noticias
                ListaConsultaNoticias consultarNews(ConjuntoPosiciones conjuntoPosicionesEnIndice, TCId feedId);

                //Recibe una posicion Inicial, el ID de Feed y retorna 'cantidad' de noticias
                //empezando desde 'posicionInicial' hacia atras (en caso de ser 0 empieza desde
                //el final del archivo)
                ListaConsultaNoticias consultarNews(TCPosicionEnLista posicionInicial, unsigned int cantidad,
                        TCId feedId);

                //Recibe un ID de feed y la posicion de una noticia en el indice. Le agrega
                //a su lista de positivos el Id de Categoria recibido en categoriaAAgregar.
                bool CategorizarNoticia(TCId feedId, TCPosicionEnLista posicionNoticia,
                        TCId categoriaAAgregar);

                //Recibe un ID de feed y la posicion de una noticia en el indice. Le agrega
                //a su lista de negativos el Id de Categoria recibido en categoriaAAgregar.
                bool DesCategorizarNoticia(TCId feedId, TCPosicionEnLista posicionNoticia,
                        TCId categoriaAEliminar);

                //cambia las listas de apariciones y no apareciones de una noticia
                //por las que recibe por parametro 
                bool cambiarListas(TCId feedID, TCPosicionEnLista posicionNoticia,
                        ListaCategorias &listaPositivos, ListaCategorias &listaNegativos);

                //devuelve la cantidad de noticias en un feed (si devuelve -1 hubo error);
                int getCantidadNoticias(TCId feedId);

                //devuelve el estado de una noticia en particular de un feed determinado
                bool getEstadoNoticia(TCPosicionEnLista posicionNoticia, TCId feedID);

                //Recibe el cojunto de categorias a reorganizar (idealmente todas las categorias que queden
                //vivas en el mapa) y una lista de feeds a reorganizar (idealmente los feeds que queden
                //vivos en feedManager.
                //Deja solo las noticias pertenecientes a los feeds vivos, y actualiza sus listas de categorias
                //positivos y negativos de acuerdo a las categoriasALimpiar (que son la categorias vivas).
                void ReorganizarArchivos(ConjuntoIdCategoria& categoriasVivas, ConjuntoFeeds &feedsVivos);
                

};

#endif
